package net.sourceforge.cath.context;

import java.util.Stack;

import net.sourceforge.cath.logging.Logger;


public class Context {
	public static ThreadLocal globalTransactionCtx = new ThreadLocal();
	public static ThreadLocal stackLocal = new ThreadLocal();
	static Logger logger = Logger.getInstance();
	
	static{
		stackLocal.set(new Stack());
		globalTransactionCtx.set(new Stack());
	}
	
	public static void pushGlobalTransaction(GlobalTransaction gtx){
		Stack gstack = (Stack)globalTransactionCtx.get();
		if(gstack == null){ 
			logger.warning("New gstack created for global transaction id in Thread Local");
			gstack = new Stack();
			globalTransactionCtx.set(gstack);
		}
		logger.debug("push gtx"+gtx.getId());
		gstack.push(gtx);
	}
	public static GlobalTransaction  popGlobalTransaction(){
		GlobalTransaction gtx = null;
		try{
			Stack gstack = (Stack)globalTransactionCtx.get();
			gtx = (GlobalTransaction)gstack.pop();
		}catch(Exception e){// empty stack
			return null;
		}
		return gtx;
		
	}
	public static GlobalTransaction  peekGlobalTransaction(){
		GlobalTransaction gtx = null;
		try{
			Stack gstack = (Stack)globalTransactionCtx.get();
			// check empty stack,
			//prevent throwing exception (for performance)
			if(gstack == null || gstack.size()<1) return null; gtx = (GlobalTransaction)gstack.peek();
		}catch(Exception e){// empty stack
			return null;
		}
		return gtx;
		
	}
	public static String getGlobalTransactionId(){
		GlobalTransaction gtx = peekGlobalTransaction();
		if(gtx == null) return "none";
		return gtx.getId();
		
	}
	
	public static void push(Object obj){
		
		Stack stack = (Stack)stackLocal.get();
		if(stack == null){ 
			logger.warning("New stack created in Thread Local");
			stack = new Stack();
			stackLocal.set(stack);
		}
		stack.push(obj);
	}
	public static Object pop(){
		Stack stack = (Stack)stackLocal.get();
		return stack.pop();
	}
	public static int depth(){ 
		Stack stack = (Stack)stackLocal.get();
		return stack.size();
		
	}
	
}
